﻿using System;
using CodeStash.Common.DTOS;
using CodeStash.Addin.Core.Interfaces;
using CodeStash.Common.Enums;
using System.ComponentModel.Composition;

namespace CodeStash.Addin.Core.Model
{
    [Serializable]
    [Export(typeof(IRestService))]
    [PartCreationPolicy(CreationPolicy.Shared)]
    public class RestService : CodeStashRestBase, IRestService
    {

        public RestService()
        {
            PageSize = 10;
        }

        /// <summary>
        /// Can the user connect to CodeStash based on the chosen login.
        /// </summary>
        /// <param name="loginDetails"></param>
        /// <returns>True if the user can connect, false otherwise.</returns>
        public bool CanConnectToCodeStash(LoginDetails loginDetails)
        {
            JSONLanguagesResult result = Utilities.GetValue<JSONLanguagesResult>(GetDataFromRestService(loginDetails));
            if (!string.IsNullOrWhiteSpace(result.ErrorMessage) || result.Languages == null || result.Languages.Count == 0)
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// Allows PageSize to be got/set
        /// </summary>
        public int PageSize { get; set; }

        /// <summary>
        /// Retrieve the languages from the service.
        /// </summary>
        public JSONLanguagesResult RetrieveLanguages()
        {
            return GetValue<JSONLanguagesResult>("GetAllLanguages");
        }

        /// <summary>
        /// Get the groups from the REST service.
        /// </summary>
        /// <returns>The groups needed.</returns>
        public JSONGroupingResult RetrieveGroups()
        {
            return GetValue<JSONGroupingResult>("GetAllGroups");
        }

        /// <summary>
        /// Call the Search service.
        /// </summary>
        /// <param name="searchText">The text to search for.</param>
        /// <param name="searchType">The type of search to perform.</param>
        /// <param name="visibility">The <see cref="CodeSnippetVisibility">visibility</see> of the item to see, e.g. search for public.</param>
        /// <param name="tags">Any tags to search on.</param>
        /// <param name="pageNumber">The page number to retrieve the search for.</param>
        /// <param name="includeRatings">A boolean value indicating whether snippet rating should be included in search or not.</param>
        /// <param name="rating">Snippet rating to search for</param>
        /// <returns></returns>
        public JSONPagesSearchResultCodeSnippet Search(string searchText, SearchType searchType,
            CodeSnippetVisibility visibility, string[] tags, int pageNumber, 
            bool includeRatings, int rating)
        {
            return Utilities.GetValue<JSONPagesSearchResultCodeSnippet>(base.Search(searchText, searchType, visibility, tags, PageSize, pageNumber, includeRatings, rating));
        }

        public JSONCodeSnippetAddSingleResult AddCodeSnippet(
                string actualCode,
                string categoryName,
                int languageId,
                string language,
                string tags,
                string description,
                string title,
                int? groupId,
                string groupName,
                CodeSnippetVisibility visibility)
        {
            JSONCodeSnippet snippet = new JSONCodeSnippet(actualCode, 0, categoryName, languageId, language, tags, description, title, groupId, groupName, visibility,0,0,0);

            return Utilities.GetValue<JSONCodeSnippetAddSingleResult>(GetDataFromRestService(snippet));
        }

        private T GetValue<T>(string restService) where T : class
        {
            return Utilities.GetValue<T>(GetDataFromRestService(restService));
        }
    }
}
